﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using FarmerJoe.ClassSettings;
using FarmerJoe.Settings;
using Styx;

namespace FarmerJoe
{
    public partial class uiExtendedOptions : Form
    {
        [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
        private static extern IntPtr CreateRoundRectRgn
            (int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);

        private bool _showLogicProcess = true;
        private bool _isLoading = true;

        private const int CS_DROPSHADOW = 0x00020000;
        protected override CreateParams CreateParams
        {
            get { CreateParams cp = base.CreateParams; cp.ClassStyle |= CS_DROPSHADOW; return cp; }
        }

        public uiExtendedOptions()
        {
            InitializeComponent();
            Region = Region.FromHrgn(CreateRoundRectRgn( 0, 0, Width-10, Height-10, 20, 20));
        }


        #region Event Handlers
        // Currently too lazy to do this properly. I just want to do it this way for now. 
        // I'll clean this up later on when I can be motivated and I'm not busy doing 100 other things.

        // Druid
        private void ucControl_ProgressBarValueChanged(object sender, EventArgs e)
        {
            // Basically enumerate the [Druid] setting class and find the Property that matches the name of 'e.SettingName' and assign the value of 'e.Value'
            // This saves us creating code for every item / setting and adds reusability

            if (_isLoading) return;

            Type type = null;
            object settingClass = null;

            switch (StyxWoW.Me.Class)
            {
                case WoWClass.Druid:
                    type = typeof(DruidSettings);
                    settingClass = FpswareSettings.Instance.Druid;
                    break;

                case WoWClass.Warlock:
                    type = typeof(WarlockSettings);
                    settingClass = FpswareSettings.Instance.Warlock;
                    break;

                case WoWClass.Hunter:
                    type = typeof(HunterSettings);
                    settingClass = FpswareSettings.Instance.Hunter;
                    break;

                case WoWClass.Priest:
                    type = typeof(PriestSettings);
                    settingClass = FpswareSettings.Instance.Priest;
                    break;

            }

            // If we hit this then something has gone wrong just bail out
            if (settingClass == null) return;

            PropertyInfo[] settingsProperties = type.GetProperties();
            foreach (PropertyInfo setting in settingsProperties.Where(setting => e.SettingName == setting.Name))
            {
                setting.SetValue(settingClass, e.Value, null);
            }

        }

        private void ucControl_DropDownValueChanged(object sender, cbEventArgs e)
        {
            // Basically enumerate the setting class and find the Property that matches the name of 'e.SettingName' and assign the value of 'e.Value'
            // This saves us creating code for every item / setting and allows reusability

            if (_isLoading) return;

            Type type = null;
            object settingClass = null;

            switch (StyxWoW.Me.Class)
            {
                    case WoWClass.Druid:
                        type = typeof(DruidSettings); 
                        settingClass = FpswareSettings.Instance.Druid;
                    break;

                    case WoWClass.Warlock:
                        type = typeof(WarlockSettings);
                        settingClass = FpswareSettings.Instance.Warlock;
                    break;

                    case WoWClass.Hunter:
                    type = typeof(HunterSettings);
                    settingClass = FpswareSettings.Instance.Hunter;
                    break;

                    case WoWClass.Priest:
                        type = typeof(PriestSettings);
                        settingClass = FpswareSettings.Instance.Priest;
                    break;

            }

            // If we hit this then something has gone wrong just bail out
            if (settingClass== null) return;

            PropertyInfo[] settingsProperties = type.GetProperties();
            foreach (PropertyInfo setting in settingsProperties.Where(setting => e.SettingName == setting.Name))
            {
                setting.SetValue(settingClass, e.Value, null);
            }
        }

        #endregion

        private void PopulateUIControls()
        {
            SuspendLayout();

            Type type = null;
            PropertyInfo[] settingsProperties = null;
            object classSpecificSetting = null;

            switch (StyxWoW.Me.Class)
            {
                case WoWClass.Druid:
                    type = typeof(DruidSettings); settingsProperties = type.GetProperties();
                    classSpecificSetting = FpswareSettings.Instance.Druid;
                    break;

                case WoWClass.Warlock:
                    type = typeof(WarlockSettings); settingsProperties = type.GetProperties();
                    classSpecificSetting = FpswareSettings.Instance.Warlock;
                    break;


                case WoWClass.Hunter:
                    type = typeof(HunterSettings); settingsProperties = type.GetProperties();
                    classSpecificSetting = FpswareSettings.Instance.Hunter;
                    break;
            }

            if (type == null) return;

            //Type type = typeof(DruidSettings); 
            //PropertyInfo[] settingsProperties = type.GetProperties();
            foreach (PropertyInfo setting in settingsProperties)
            {
                PropertyInfo pInfo = type.GetProperty(setting.Name);
                object propValue = pInfo.GetValue(classSpecificSetting, null);

                //foreach (GroupBox gb in from TabPage tab in tabControl1.Controls from GroupBox gb in tab.Controls select gb)
                    foreach (object obj in panelHost.Controls)
                    {
                        // Populate all combo boxes, this will be the most common
                        if (obj is ucDropdown)
                        {
                            var cbox = (ucDropdown)obj;
                            cbox.ValueChanged += ucControl_DropDownValueChanged;

                            if (cbox.SettingName == setting.Name && cbox.Value != propValue.ToString())
                            {
                                cbox.Value = propValue.ToString();
                                break;
                            }
                        }

                            // Populate all progress bars, mostly for health or mana 
                        else if (obj is ucProgressBar)
                        {
                            var pbar = (ucProgressBar)obj;
                            pbar.ValueChanged += ucControl_ProgressBarValueChanged;


                            if (pbar.SettingName == pInfo.Name)
                            {
                                pbar.Value = (int)propValue;
                                break;
                            }
                        }
                    }
            }

            _isLoading = false;
            ResumeLayout();
        }





        private void Form2_Deactivate(object sender, System.EventArgs e)
        {
            //this.Close();
        }

        private void Form2_Activated(object sender, System.EventArgs e)
        {
            this.Left = Owner.Left + Owner.Width + 2;
            this.Top = Owner.Top;

        }

        private void btnClose_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        public string FormHeading
        {
            set { label1.Text = value; }
        }

        public bool Loading { get; set; }

        public void AddDropDown(string label, string settingName, List<string> options, string tooltipTitle, string tooltipText)
        {
            ucDropdown uc = new ucDropdown {Label = label, SettingName = settingName, TooltipTitle = tooltipTitle, TooltipText = tooltipText};
            foreach (string s in options) uc.DropDownItems.Add(s);

            uc.Top = (ShowLogicProcess ? panelHost.Controls.Count * 25 : (panelHost.Controls.Count-1) * 25) + 6;
            uc.Left = 4;
            
            panelHost.Controls.Add(uc);
        }

        public void AddProgressBar(string label, string settingName, int minValue,int maxValue, string tooltipTitle, string tooltipText)
        {
            ucProgressBar uc = new ucProgressBar { Label = label, SettingName = settingName,MaxValue = maxValue, MinValue = minValue,TooltipTitle = tooltipTitle,TooltipText = tooltipText};

            uc.Top = (ShowLogicProcess ? panelHost.Controls.Count * 25 : (panelHost.Controls.Count - 1) * 25) + 6;
            uc.Left = 4;

            panelHost.Controls.Add(uc);
        }

        public bool ShowLogicProcess
        {
            get
            {
                //ucLogicProcess.Visible = true;
                return _showLogicProcess;
            }
            set
            {
                _showLogicProcess = value;
                ucLogicProcess.Visible = _showLogicProcess;
                if (!_showLogicProcess) ucLogicProcess.SendToBack();
            }
        }

        private void Form2_Shown(object sender, System.EventArgs e)
        {
            //int countOfControls = (panelHost.Controls.Count * 25) + 6;
            //Height = countOfControls + panel1.Height + panel2.Height + 1000;
            _isLoading = true;

            PopulateUIControls();
            

            Loading = false;
        }

    }

}
